package task5.chat;

import task5.Util;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 该类用于实现服务器端的多线程，维护客户端通道列表，既可以让服务端接收客户端数据，也可以回传给客户端
 * 每一个客户端与服务器发起聊天，就是一个通道
 */
public class ChatChannel implements Runnable{

    // 定义通道列表管理所有的通道
    public static List<ChatChannel> chat_list = new ArrayList<>();

    // 定义输入输出流
    private DataInputStream dataInputStream;
    private DataOutputStream dataOutputStream;
    // 定义客户端名字
    private String name;
    // 判断当前通道是否正在运行
    private boolean isRunning = true;

    public ChatChannel(Socket socket) {
        try {
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            this.name = dataInputStream.readUTF();
            System.out.println(this.name + " 进入聊天室。。。");
            // 告知当前客户端连接服务器成功
            this.send("欢迎 " + this.name + " 进入聊天室！");
            // 告知其他已连接客户端当前客户端连接成功
            this.sendAll(this.name + " 进入聊天室。。。",true);

        }catch (IOException e) {
            e.printStackTrace();
            // 若当前通道出现异常，则关闭
            isRunning = false;
            Util.close(dataInputStream,dataOutputStream);
        }
    }

    /**
     * 服务器向其他客户端发送消息
     * @param message 发送消息内容
     * @param flag 判断是否是系统消息还是聊天内容
     */
    private void sendAll(String message, boolean flag) {
        // 对每个通道中的客户端发送
        for (ChatChannel chatChannel: chat_list){
            if (chatChannel != this){
                if (flag)
                    chatChannel.send("系统消息：" + message);
                else
                    chatChannel.send(this.name + " 说：" + message);
            }
        }
    }

    /**
     * 从服务器向客户端发送消息
     * @param message 发送消息内容
     */
    private void send(String message) {
        if (message != null && !message.equals("")){
            try {
                dataOutputStream.writeUTF(message);
                dataOutputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
                // 若当前通道出现异常，则关闭,并且移除当前通道
                isRunning = false;
                Util.close(dataOutputStream);
                chat_list.remove(this);
            }
        }
    }

    /**
     * 服务器接收从客户端传来的消息
     * @return
     */
    private String receive() {
        String message = "";

        try {
            message = dataInputStream.readUTF();

        }catch (EOFException e){
            // 表示结束，关闭
            isRunning = false;
            Util.close(dataInputStream);
            System.out.println(this.name + " 退出聊天室。。。");
            this.sendAll(this.name + " 退出聊天室！",true);
            chat_list.remove(this);
        }
        catch (IOException e) {
            e.printStackTrace();
            // 若当前通道出现异常，则关闭，并从通道列表里移除
            isRunning = false;
            Util.close(dataInputStream);
            chat_list.remove(this);

        }
        return message;
    }

    @Override
    public void run() {
        while (isRunning){
            String message = receive();
            if (message != null && !message.equals(""))
                sendAll(message,false);
        }
    }
}
